package com.lanou3g.ptp.organize.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lanou3g.ptp.entity.Clazz;
import com.lanou3g.ptp.entity.College;
import com.lanou3g.ptp.entity.Major;
import com.lanou3g.ptp.entity.User;
import com.lanou3g.ptp.organize.mapper.ClazzMapper;
import com.lanou3g.ptp.organize.service.ClazzService;
import com.lanou3g.ptp.organize.service.CollegeService;
import com.lanou3g.ptp.organize.service.MajorService;
import com.lanou3g.ptp.student.service.StudentService;
import com.lanou3g.ptp.teacher.service.TeacherService;
import com.lanou3g.ptp.user.service.UserService;
import com.lanou3g.ptp.vo.ClazzCondition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service(timeout = 10000)
public class ClazzServiceImpl implements ClazzService {

    @Autowired
    private CollegeService collegeService;
    @Autowired
    private MajorService majorService;
    @Reference(lazy = true)
    private StudentService studentService;
    @Reference(lazy = true)
    private TeacherService teacherService;
    @Reference(lazy = true)
    private UserService userService;
    @Autowired
    private ClazzMapper clazzMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Value("${REDIS_CLAZZ_KEY_PREFIX}")
    private String REDIS_CLAZZ_KEY_PREFIX;
    @Value("${REDIS_CLAZZ_KEY_EXPIRE}")
    private Long REDIS_CLAZZ_KEY_EXPIRE;

    @Override
    public void addClazz(Clazz clazz) {
        Date now = new Date();
        clazz.setCreateTime(now);
        clazz.setUpdateTime(now);
        clazz.setStatus(0);
        clazzMapper.addMajor(clazz);
    }

    @Override
    public Clazz findById(Long id) {
        String redisKey = REDIS_CLAZZ_KEY_PREFIX + id;
        String sc = redisTemplate.opsForValue().get(redisKey);
        if (sc == null) {
            Clazz clazz = clazzMapper.findById(id);
            String s = JSON.toJSONString(clazz);
            redisTemplate.opsForValue().set(redisKey, s, REDIS_CLAZZ_KEY_EXPIRE, TimeUnit.MINUTES);
            return clazz;
        } else {
            Clazz clazz = JSON.parseObject(sc, Clazz.class);
            redisTemplate.expire(redisKey, REDIS_CLAZZ_KEY_EXPIRE, TimeUnit.MINUTES);
            return clazz;
        }
    }

    @Override
    public List<Clazz> findByIds(Long[] ids) {
        List<Clazz> clazzes = clazzMapper.findByIds(ids);
        return clazzes;
    }

    @Override
    public Clazz findByName(String name) {
        Clazz clazz = clazzMapper.findByName(name);
        return clazz;
    }

    @Override
    public List<Clazz> findAll() {
        List<Clazz> clazzes = clazzMapper.findAll();
        return clazzes;
    }

    @Override
    public void updateById(Clazz clazz) {
        Major major = majorService.findById(clazz.getMajorId());
        clazz.setUpdateTime(new Date());
        clazzMapper.updateById(clazz);
        College college = collegeService.findById(major.getCollegeId());
        collegeService.cacheColleges(college.getSchoolId());
    }

    @Override
    public void deleteById(Long id) {
        Clazz clazz = findById(id);
        clazzMapper.deleteById(id);
        Major major = majorService.findById(clazz.getId());
        College college = collegeService.findById(major.getCollegeId());
        collegeService.cacheColleges(college.getSchoolId());
    }

    @Override
    public void deleteByIds(Long[] ids) {
        clazzMapper.deleteByIds(ids);
    }

    @Override
    public PageInfo<Clazz> findByPage(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        List<Clazz> list = findAll();
        for (Clazz clazz : list) {
            Major major = majorService.findById(clazz.getMajorId());
            College college = collegeService.findById(major.getCollegeId());
            Long leaderId = clazz.getLeaderId();
            Long monitorId = clazz.getMonitorId();
            if (leaderId != null) {
                User leader = userService.userById(leaderId);
                clazz.setLeaderName(leader.getName());
            }
            if (monitorId != null) {
                User monitor = userService.userById(monitorId);
                clazz.setMonitorName(monitor.getName());
            }
            Long count = studentService.findClazzId(clazz.getId());

            clazz.setCollegeId(college.getId());
            clazz.setCollegeName(college.getName());
            clazz.setMajorName(major.getName());
            clazz.setCount(count);
            clazz.setParentNode(major.getName());
        }
        return new PageInfo<>(list);
    }

    @Override
    public List<Clazz> findByMajorId(Long majorId) {
        List<Clazz> clazzes = clazzMapper.findByMajorId(majorId);
        Major major = majorService.findById(majorId);
        for (Clazz clazz : clazzes) {
            Long monitorId = clazz.getMonitorId();
            if (monitorId != null) {
                User monitor = userService.userById(monitorId);
                clazz.setMonitorName(monitor.getName());
            }
            User leader = userService.userById(clazz.getLeaderId());
            if (leader != null) {
                clazz.setLeaderName(leader.getName());
            }
            clazz.setParentNode(major.getName());
            clazz.setParentId(majorId);
            clazz.setLevel(3);
        }
        return clazzes;
    }

    @Override
    public PageInfo<Clazz> findByPage(Integer page, Integer size, Long majorId, String grade) {
        PageHelper.startPage(page, size);
        ClazzCondition condition = new ClazzCondition(majorId, grade);
        List<Clazz> list = clazzMapper.findByCondition(condition);
        return new PageInfo<>(list);
    }
}
